﻿using System;
using System.Collections.Generic;

namespace tuimg.structs
{
    internal struct struct_path
    {
        internal static struct_path Empty = new struct_path { };
        internal enum_path_method method;
        internal struct_path_point p0;
        internal struct_path_point p1;
        internal struct_path_point p2;

        internal struct_path Scale(decimal per)
        {
            switch (method)
            {
                case enum_path_method.Move:
                    p1.Scale(per);
                    break;
                case enum_path_method.Quadratic_Bezier_Curve:
                    p0.Scale(per);
                    p1.Scale(per);
                    p2.Scale(per);
                    break;
                default:
                    p0.Scale(per);
                    p1.Scale(per);
                    break;
            }
            return this;
        }
        internal struct_path Move(int x, int y)
        {
            switch (method)
            {
                case enum_path_method.Move:
                    p1.Move(x, y);
                    break;
                case enum_path_method.Quadratic_Bezier_Curve:
                    p0.Move(x,y);
                    p1.Move(x,y);
                    p2.Move(x,y);
                    break;
                default:
                    p0.Move(x, y);
                    p1.Move(x, y);
                    break;
            }
            return this;
        }
    }
    internal struct struct_path_point
    {
        internal int x;
        internal int y;

        internal struct_path_point Scale(decimal per)
        {
            if (per == 1) return this;
            x = (int)(x * per);
            y = (int)(y * per);
            return this;
        }
        internal struct_path_point Move(int x, int y)
        {
            this.x += x;
            this.y += y;
            return this;
        }

        // 垂直翻转
        internal struct_path_point Flip_vertical(struct_path_viewbox viewbox)
        {
            y = viewbox._y - y;
            return this;
        }
        // 水平翻转
        internal struct_path_point Flip_horizontal(struct_path_viewbox viewbox)
        {
            x = viewbox._x - x;
            return this;
        }

        public override bool Equals(object obj)
        {
            return obj is struct_path_point point &&
                   x == point.x &&
                   y == point.y;
        }

        public override int GetHashCode()
        {
            int hashCode = 1502939027;
            hashCode = hashCode * -1521134295 + x.GetHashCode();
            hashCode = hashCode * -1521134295 + y.GetHashCode();
            return hashCode;
        }
        public struct_path_point Copy()
        {
            return new struct_path_point { x = x , y  =y};
        }
        public static bool operator ==(struct_path_point a, struct_path_point b)
        {
            return a.x == b.x && a.y == b.y;
        }
        public static bool operator !=(struct_path_point a, struct_path_point b)
        {
            return a.x != b.x || a.y != b.y;
        }
    }
    internal struct struct_path_viewbox
    {
        internal int x_min;
        internal int y_min;
        internal int x_max;
        internal int y_max;

        internal int _x;
        internal int _y;
    }
    internal struct struct_path_vector_f0
    {
        internal int x;
        internal int y;
        internal byte dir;
        internal IEnumerable<struct_path_vector_f0> ReadNexts()
        {
            if ((dir & const_path_dir_mask.N) != 0) yield return Move(0, -1,0b11010000);
            if ((dir & const_path_dir_mask.S) != 0) yield return Move(0, 1, 0b01110000);
            if ((dir & const_path_dir_mask.W) != 0) yield return Move(-1, 0,0b10110000);
            if ((dir & const_path_dir_mask.E) != 0) yield return Move(1, 0, 0b11100000);
        }

        internal struct_path_vector_f0 Move(short x, short y, byte dir)
        {
            return new struct_path_vector_f0 { x = this.x+ x, y = this.y+ y, dir = dir };
        }
    }
    internal struct struct_grid_draw_point
    {
        internal double t;
        internal double t2;
    }
    internal struct const_path_dir_mask
    {
        /// <summary>
        /// 北
        /// </summary>
        public const byte N = 0b10000000;
        /// <summary>
        /// 东
        /// </summary>
        public const byte E = 0b01000000;
        /// <summary>
        /// 南
        /// </summary>
        public const byte S = 0b00100000;
        /// <summary>
        /// 西
        /// </summary>
        public const byte W = 0b00010000;
        /// <summary>
        /// 东北
        /// </summary>
        public const byte NE = 0b00001000;
        /// <summary>
        /// 西北
        /// </summary>
        public const byte NW = 0b00000100;
        /// <summary>
        /// 东南
        /// </summary>
        public const byte SE = 0b00000010;
        /// <summary>
        /// 西南
        /// </summary>
        public const byte SW = 0b00000001;
    }
    internal enum enum_path_method
    {
        Move = 0,
        Line = 1,
        Quadratic_Bezier_Curve = 2,
    }
}
